﻿#include "RankManager.h"

RankManager::RankManager()
	:
	// 初始化活动管理类成员
#define RANK_REGISTER(RankType, MiscType, iRankMaxNum, RankXXXManager, stRankXXXMgr) stRankXXXMgr(RankType, MiscType, iRankMaxNum),
#include "RankRegister.h"
#undef RANK_REGISTER
	_iUseless(0),
	_iAverageLevel(0),
	_iAverageLevelRefreshTime(0)

{
#define RANK_REGISTER(RankType, MiscType, iRankMaxNum, RankXXXManager, stRankXXXMgr) \
	{\
		uint32_t iRankType = (uint32_t)RankType; \
		RankBaseManager* pRankBaseManager = (RankBaseManager*)&stRankXXXMgr; \
		_mRankMgr[iRankType] = pRankBaseManager; \
	}
#include "RankRegister.h"
#undef RANK_REGISTER
}

RankManager::~RankManager()
{
}

void RankManager::fillRankKey(JceData::CacheMiscRankKey& stRankKey, uint32_t iObjId, int64_t iRankParam1, int64_t iRankParam2, int64_t iExtraParam1, const string& sExtdata)
{
	stRankKey.iObjId = iObjId;
	stRankKey.iTime = TUtil::safeSub(uint32_t(-1), TDateTime::getNow());
	stRankKey.iRankParam1 = iRankParam1;
	stRankKey.iRankParam2 = iRankParam2;
	stRankKey.iExtraParam1 = iExtraParam1;
	stRankKey.sExtraParam = sExtdata;
}

void RankManager::updateRank(uint32_t iRankType, uint32_t iSubId, uint32_t iObjId, int64_t iRankParam1, int64_t iRankParam2, int64_t iExtraParam1, const string& sExtdata)
{
	JceData::CacheMiscRankKey stRankKey;
	fillRankKey(stRankKey, iObjId, iRankParam1, iRankParam2, iExtraParam1, sExtdata);

	map<uint32_t, RankBaseManager*>::iterator it = _mRankMgr.find(iRankType);
	if (it != _mRankMgr.end())
	{
		RankBaseManager* pRankBaseManager = it->second;
		if (pRankBaseManager != NULL)
		{
			pRankBaseManager->updateRank(iSubId, iObjId, stRankKey);
		}
	}
}

void RankManager::updateAreaRank(uint32_t iRankType, uint32_t iSubId, uint32_t iObjId, uint32_t iRankParam, const string& sExtData /*= ""*/)
{
	MsgServerArea::MsgUpdateRankData stMsg;
	stMsg.set_ranktype(iRankType);
	stMsg.set_subid(iSubId);
	stMsg.set_objid(iObjId);
	stMsg.set_rankparam(iRankParam);
	stMsg.set_extdata(sExtData);
	SceneService::getSingleton().sendCmdToOtherServerBySuper(stMsg, ServerType_Area, 0, false);
}


void RankManager::clearAreaRank(uint32_t iRankType, uint32_t iSubId)
{
	MsgServerArea::MsgClearRankData stMsg;
	stMsg.set_ranktype(iRankType);
	stMsg.set_subid(iSubId);

	SceneService::getSingleton().sendCmdToOtherServerBySuper(stMsg, ServerType_Area, 0, false);
}


void RankManager::getRankList(int32_t iRankType, uint32_t iSubId, uint32_t iStartIndex, uint32_t iRankNum, vector<RankData>& vRankData)
{
	map<uint32_t, RankBaseManager*>::iterator it = _mRankMgr.find(iRankType);
	if (it != _mRankMgr.end())
	{
		RankBaseManager* pRankBaseManager = it->second;
		if (pRankBaseManager != NULL)
		{
			pRankBaseManager->getRankList(iSubId, iStartIndex, iRankNum, vRankData);
		}
	}
}

void RankManager::getTiedRankList(int32_t iRankType, uint32_t iSubId, uint32_t iMaxRankId, uint32_t iRankNum, vector<RankData>& vRankData)
{
	map<uint32_t, RankBaseManager*>::iterator it = _mRankMgr.find(iRankType);
	if (it != _mRankMgr.end())
	{
		RankBaseManager* pRankBaseManager = it->second;
		if (pRankBaseManager != NULL)
		{
			pRankBaseManager->getTiedRankList(iSubId, iMaxRankId, iRankNum, vRankData);
		}
	}
}

RankData RankManager::getSelfRank(int32_t iRankType, uint32_t iSubId, uint32_t iObjId)
{
	map<uint32_t, RankBaseManager*>::iterator it = _mRankMgr.find(iRankType);
	if (it != _mRankMgr.end())
	{
		RankBaseManager* pRankBaseManager = it->second;
		if (pRankBaseManager != NULL)
		{
			return pRankBaseManager->getSelfRank(iSubId, iObjId);
		}
	}

	return RankData();
}

RankData RankManager::getTiedSelfRank(int32_t iRankType, uint32_t iSubId, uint32_t iObjId)
{
	map<uint32_t, RankBaseManager*>::iterator it = _mRankMgr.find(iRankType);
	if (it != _mRankMgr.end())
	{
		RankBaseManager* pRankBaseManager = it->second;
		if (pRankBaseManager != NULL)
		{
			return pRankBaseManager->getTiedSelfRank(iSubId, iObjId);
		}
	}

	return RankData();
}

uint32_t RankManager::getUserAverageLevel()
{
	static uint32_t iAverageLevelUserNum = 200;

	uint32_t iNow = TDateTime::getNow();
	if (TDateTime::getDate(iNow) > TDateTime::getDate(_iAverageLevelRefreshTime))
	{
		map<uint32_t, RankBaseManager*>::iterator it = _mRankMgr.find(ProtoMsg::RankType_Level);
		if (it != _mRankMgr.end())
		{
			RankBaseManager* pRankBaseManager = it->second;
			if (pRankBaseManager != NULL)
			{
				map<JceData::CacheMiscRankKey, uint32_t>& mRank = pRankBaseManager->getRankMap(0);

				uint32_t iRankNum = 0;
				uint32_t iTotalLevel = 0;
				map<JceData::CacheMiscRankKey, uint32_t>::reverse_iterator it = mRank.rbegin();
				for (; it != mRank.rend(); it++)
				{
					TUtil::safeAddInPlace(iTotalLevel, it->first.iRankParam1);

					iRankNum++;
					if (iRankNum >= iAverageLevelUserNum)
					{
						break;
					}
				}

				_iAverageLevel = (iRankNum == 0) ? 0 : iTotalLevel / iRankNum;
			}
		}

		_iAverageLevelRefreshTime = iNow;
	}

	return _iAverageLevel;
}

void RankManager::clearAllRank()
{
	map<uint32_t, RankBaseManager*>::iterator it = _mRankMgr.begin();
	for (; it != _mRankMgr.end(); it++)
	{
		RankBaseManager* pRankBaseManager = it->second;
		if (pRankBaseManager != NULL)
		{
			pRankBaseManager->clearRankList();
		}
	}
}

void RankManager::clearRank(int32_t iRankType)
{
	map<uint32_t, RankBaseManager*>::iterator it = _mRankMgr.find(iRankType);
	if (it != _mRankMgr.end())
	{
		RankBaseManager* pRankBaseManager = it->second;
		if (pRankBaseManager != NULL)
		{
			return pRankBaseManager->clearRankList();
		}
	}
}

void RankManager::clearSubRank(int32_t iRankType, uint32_t iSubId)
{
	map<uint32_t, RankBaseManager*>::iterator it = _mRankMgr.find(iRankType);
	if (it != _mRankMgr.end())
	{
		RankBaseManager* pRankBaseManager = it->second;
		if (pRankBaseManager != NULL)
		{
			return pRankBaseManager->clearSubRankList(iSubId);
		}
	}
}

void RankManager::delFromRank(int32_t iRankType, uint32_t iSubId, uint32_t iObjId)
{
	map<uint32_t, RankBaseManager*>::iterator it = _mRankMgr.find(iRankType);
	if (it != _mRankMgr.end())
	{
		RankBaseManager* pRankBaseManager = it->second;
		if (pRankBaseManager != NULL)
		{
			return pRankBaseManager->delFromRank(iSubId, iObjId);
		}
	}
}

int32_t RankManager::getAreaList(uint32_t iRankType, uint32_t iSubRankType, uint32_t iStartIndex, uint32_t iRankNum, uint32_t iCharid, uint32_t seqid)
{
	MsgServerArea::MsgGetRankListRequest stMsg;
	stMsg.set_zoneid(getZoneId());
	stMsg.set_sceneid(SceneService::getSingleton().getServerID());
	stMsg.set_charid(iCharid);
	stMsg.set_seqid(seqid);
	stMsg.set_ranktype(iRankType);
	stMsg.set_subid(iSubRankType);
	stMsg.set_startrank(iStartIndex);
	stMsg.set_endrank(iRankNum);

	if (!SceneService::getSingleton().sendCmdToOtherServerBySuper(stMsg, ServerType_Area, 0, false))
	{
		return ProtoMsg::Code_System_SendProtoToSupperError;
	}

	return 0;
}

int32_t RankManager::getAreaBatchList(const ProtoMsg::Msg_Rank_GetAreaSubBatchList_CS & msgRequest, uint32_t seqid, uint32_t charid)
{
	MsgServerArea::MsgGetBatchRankListRequest stMsg;
	stMsg.set_zoneid(getZoneId());
	stMsg.set_sceneid(SceneService::getSingleton().getServerID());
	stMsg.set_charid(charid);
	stMsg.set_seqid(seqid);
	stMsg.set_ranktype(msgRequest.ranktype());
	stMsg.set_startrank(1);
	stMsg.set_endrank(msgRequest.ranknum());
	for (int32_t i = 0; i < msgRequest.subid_size(); ++i)
	{
		stMsg.add_subid(msgRequest.subid(i));
	}

	if (!SceneService::getSingleton().sendCmdToOtherServerBySuper(stMsg, ServerType_Area, 0, false))
	{
		return ProtoMsg::Code_System_SendProtoToSupperError;
	}

	return 0;
}